package org.example.demoschedules.service;

import lombok.extern.slf4j.Slf4j;
import org.example.demoschedules.model.OrderedMap;

import java.time.LocalDate;
import java.util.List;
import java.util.Set;

/**
 * 工作日排班，例如行政班等固定工作日上班节假日不上班的
 *
 * @author 单红宇
 * @since 2024-10-16 10:26:43
 */
@Slf4j
public class ScheduleByWorkday {

    /**
     * 工作日排班，例如行政班等固定工作日上班节假日不上班的。
     * 比较简单：直接将所有用户从指定日期开始每天全部安排到工作日中。
     *
     * @param startDate        开始排班日期
     * @param members          所有用户集合
     * @param nonWorkingDates  完全不排班的日期集合，例如是周一到周五但是指定周五不排班
     * @param mustWorkingDates 比如上班的日期集合，周六周日默认不排班，这里指定上班的就会排班。例如我国的调休可能安排周六或周日上班。优先级高于nonWorkingDates。
     * @param days             排班天数
     * @return 排班集合结果
     */
    public OrderedMap<String, OrderedMap<LocalDate, WorkStatus>> generateSchedule(
            LocalDate startDate, List<String> members,
            Set<LocalDate> nonWorkingDates, Set<LocalDate> mustWorkingDates, int days) {
        // 1.先按默认的周一到周五排班，从startDate开始，循环数量=days
        // 2.根据nonWorkingDates删除排班
        // 3.对mustWorkingDates明确上班的日期进行排班
        OrderedMap<String, OrderedMap<LocalDate, WorkStatus>> schedules = new OrderedMap<>();

        // 初始化每个用户的排班表
        for (String member : members) {
            OrderedMap<LocalDate, WorkStatus> userSchedule = new OrderedMap<>();
            for (int i = 0; i < days; i++) {
                LocalDate date = startDate.plusDays(i);
                if (mustWorkingDates.contains(date)) {
                    userSchedule.put(date, WorkStatus.WORK);
                } else if (nonWorkingDates.contains(date)) {
                    userSchedule.put(date, WorkStatus.REST);
                } else {
                    userSchedule.put(date, date.getDayOfWeek().getValue() <= 5 ? WorkStatus.WORK : WorkStatus.REST);
                }
            }
            schedules.put(member, userSchedule);
        }

        return schedules;
    }

}
